/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.app.controller.cart;

import com.shop.cereshop.app.annotation.NoRepeatSubmit;
import com.shop.cereshop.app.annotation.NoRepeatWebLog;
import com.shop.cereshop.app.page.cart.CartTotalPriceResult;
import com.shop.cereshop.app.page.cart.ShopCart;
import com.shop.cereshop.app.page.product.ProductSkus;
import com.shop.cereshop.app.param.cart.*;
import com.shop.cereshop.app.service.cart.CereShopCartService;
import com.shop.cereshop.app.service.product.CereProductSkuService;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.app.redis.service.api.StringRedisService;
import com.shop.cereshop.commons.utils.GsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 购物车模块
 */
@RestController
@RequestMapping("cart")
/**
 * 注解方式生成日志对象，指定topic生成对象类名
 */
@Slf4j(topic = "ShopCartController")
@Api(value = "购物车模块", tags = "购物车模块")
public class ShopCartController {

    @Autowired
    private CereShopCartService cereShopCartService;

    @Autowired
    private StringRedisService stringRedisService;

    @Autowired
    private CereProductSkuService cereProductSkuService;

    /**
     * 加入购物车
     * @param param
     * @return
     */
    @PostMapping("addCart")
    @NoRepeatSubmit
    @ApiOperation(value = "☆加入购物车")
    @NoRepeatWebLog
    public Result addCart(@RequestBody AddCartParam param, HttpServletRequest request)  throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.addCart(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"加入购物车", GsonUtil.objectToGson(param));
    }

    /**
     * 更换规格
     * @param param
     * @return
     */
    @RequestMapping(value = "updateSku", method = {RequestMethod.PUT, RequestMethod.POST})
    @NoRepeatSubmit
    @ApiOperation(value = "更换规格")
    @NoRepeatWebLog
    public Result updateSku(@RequestBody UpdateSkuParam param, HttpServletRequest request)  throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.updateSku(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"更换规格", GsonUtil.objectToGson(param));
    }

    /**
     * 批量加入购物车
     * @param param
     * @return
     */
    @PostMapping("addBatchCart")
    @NoRepeatSubmit
    @ApiOperation(value = "批量加入购物车")
    @NoRepeatWebLog
    public Result addBatchCart(@RequestBody BatchCartParam param, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.addBatchCart(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"批量加入购物车", GsonUtil.objectToGson(param));
    }

    /**
     * 再次购买
     * @return
     */
    @RequestMapping(value = "buyAgain", method = {RequestMethod.PUT, RequestMethod.POST})
    @ApiOperation(value = "再次购买")
    @NoRepeatWebLog
    public Result buyAgain(@RequestBody BuyerAgainParam param,HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.buyAgain(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"再次购买", GsonUtil.objectToGson(param));
    }

    /**
     * 修改购物车商品数量
     * @param param
     * @return
     */
    @RequestMapping(value = "updateNumber", method = {RequestMethod.PUT})
    @NoRepeatSubmit
    @ApiOperation(value = "☆修改购物车商品数量")
    @NoRepeatWebLog
    public Result updateNumber(@RequestBody CartUpdateParam param, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.updateNumber(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"修改购物车商品数量", GsonUtil.objectToGson(param));
    }

    /**
     * 删除购物车商品
     * @param param
     * @return
     */
    @RequestMapping(value = "delete", method = {RequestMethod.DELETE})
    @NoRepeatSubmit
    @ApiOperation(value = "☆删除购物车商品")
    @NoRepeatWebLog
    public Result delete(@RequestBody DeleteParam param, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.delete(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"删除购物车商品", GsonUtil.objectToGson(param));
    }

    /**
     * 清空购物车
     * @return
     */
    @RequestMapping(value = "deleteAll", method = {RequestMethod.DELETE})
    @NoRepeatSubmit
    @ApiOperation(value = "☆清空购物车")
    @NoRepeatWebLog
    public Result deleteAll(HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.deleteAll(user.getBuyerUserId());
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"清空购物车","");
    }

    /**
     * 选中商品
     * @return
     */
    @RequestMapping(value = "selected", method = {RequestMethod.POST})
    @NoRepeatSubmit
    @ApiOperation(value = "☆选中商品")
    @NoRepeatWebLog
    public Result selected(@RequestBody SelectedParam param, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereShopCartService.selected(param,user);
        return new Result(CoReturnFormat.SUCCESS,user.getWechatName(),"选中商品", GsonUtil.objectToGson(param));
    }

    /**
     * 购物车查询
     * @return
     */
    @GetMapping("getCart")
    @ApiOperation(value = "☆购物车查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "search", value = "搜索内容", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "productType", value = "搜索类型：固定传值3", required = false, dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "商品售卖类型 1-到店核销 2-电商购 3-同城送", required = false, dataType = "Integer", paramType = "query"),
    })

    public Result<List<ShopCart>> getCart(String search, Integer productType,Integer type, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        List<ShopCart> list=cereShopCartService.getCart(search,productType,user,type);
        return new Result(list,CoReturnFormat.SUCCESS);
    }

    /**
     * 计算购物车内某类商品被勾选的总价格（含优惠券计算）
     * @return
     */
    @GetMapping("calculateSelectedTotalPrice")
    @ApiOperation(value = "☆计算购物车内某类商品被勾选的总价格（含优惠券计算）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "商品售卖类型 1-到店核销 2-电商购 3-同城送", required = true, dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "receiveId", value = "收货地址id", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "cache", value = "确定下单(传1会缓存订单/购物车 结算按钮使用)", required = false, dataType = "Long", paramType = "query"),
    })
    public Result<CartTotalPriceResult> calculateSelectedTotalPrice(Integer type, Long receiveId,Long cache, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        CartTotalPriceResult result = cereShopCartService.calculateSelectedTotalPrice(user, type, receiveId);
        result.setType( type);
        if (cache != null && cache == 1){
            //将这次查询的结果放入到redis缓存中
            //设置半小时有效期，创建key，返回给前端
            // 生成唯一的缓存key：cart:settlement:用户ID:UUID
            String cacheKey = "cart:settlement:" + user.getBuyerUserId() + ":" + UUID.randomUUID().toString().replace("-", "");
            // 将结果序列化为JSON字符串存入Redis，设置半小时有效期（30分钟 = 1800秒 = 1800000毫秒）
            String resultJson = GsonUtil.objectToGson(result);
            stringRedisService.set(cacheKey, resultJson, 1800000L);
            // 将key设置到返回结果中，供前端使用
            result.setKey(cacheKey);
        }
        return new Result(result, CoReturnFormat.SUCCESS);
    }

    /**
     * 单商品结算
     * @return
     */

    @GetMapping("singleSettlement")
    @ApiOperation(value = "☆单商品结算")
    public Result<CartTotalPriceResult> singleSettlement(AddCartParam suk, HttpServletRequest request) throws CoBusinessException{
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        ProductSkus sku2 = cereProductSkuService.findSku(suk.getSkuId());
        DeleteParam deleteParam = new DeleteParam();
        deleteParam.setIds(Arrays.asList(suk.getSkuId()));
        cereShopCartService.delete(deleteParam,user);//先删除
        cereShopCartService.addCart(suk,user);//添加到购物车
        SelectedParam selectedParam = new SelectedParam();
        selectedParam.setSkuId(suk.getSkuId());
        selectedParam.setSelected(2);
        cereShopCartService.selected(selectedParam,user);//取消其他选中
        selectedParam.setSelected(1);
        cereShopCartService.selected(selectedParam,user);//选中
        CartTotalPriceResult result = cereShopCartService.calculateSelectedTotalPrice(user, sku2.getType(), suk.getReceiveId());
        result.setType(sku2.getType());
        //将这次查询的结果放入到redis缓存中
        //设置半小时有效期，创建key，返回给前端
        // 生成唯一的缓存key：cart:settlement:用户ID:UUID
        String cacheKey = "cart:settlement:" + user.getBuyerUserId() + ":" + UUID.randomUUID().toString().replace("-", "");
        // 将结果序列化为JSON字符串存入Redis，设置半小时有效期（30分钟 = 1800秒 = 1800000毫秒）
        String resultJson = GsonUtil.objectToGson(result);
        stringRedisService.set(cacheKey, resultJson, 1800000L);
        // 将key设置到返回结果中，供前端使用
        result.setKey(cacheKey);

        return new Result(result, CoReturnFormat.SUCCESS);

    }
    /**
     * 清空失效购物车商品
     * @return
     */
    @GetMapping("clearInvalidSku")
    @ApiOperation(value = "清空失效购物车商品")
    public Result<Boolean> clearInvalidSku(HttpServletRequest request) throws CoBusinessException {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        Boolean result=cereShopCartService.clearInvalidSku(user.getBuyerUserId());
        return new Result(result,CoReturnFormat.SUCCESS);
    }
}
